﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Modbus.Device;
using System.IO.Ports;
using CCWin;
using Utils;
using ModbusTest.Config;
namespace ModbusTest
{
     
    public partial class frmMain : CCWin.Skin_Metro
    {
        Configer cfg;
        string _currentModule;
        ModuleConfigContainer moduleConfigs;
        ModuleConfig CurrentModuleCfg;
        SerialPort COM_PLC1 = new SerialPort();
        SerialPort COM_PLC2 = new SerialPort();
        //SerialPort COM_PLC3 = new SerialPort();
        //SerialPort COM_KQ = new SerialPort();
        GasPressureTester gasTester;
        ModbusMaster_PLC PLC1;
        ModbusMaster_PLC PLC2;
   //     ModbusMaster_PLC PLC3;
        FrmDisplay disPLC1;
        FrmDisplay disPLC2;
  //      FrmDisplay disPLC3;
        List<FrmDisplay> displays = new List<FrmDisplay>();
        List<ModbusMaster_PLC> modbusPlcs = new List<ModbusMaster_PLC>();
        List<SaveItem> sis=new List<SaveItem>();
        public frmMain(string CurrentModule)
        {
            _currentModule = CurrentModule;
            InitializeComponent();
      
        }

        private void closebtn_Click(object sender, EventArgs e)
        {

        }

        private void openbtn_Click(object sender, EventArgs e)
        {

        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            InitialControlValues();
            ConfigToUISetting();
            UpdateSettingToSerialPortsAndUI();
            moduleConfigs = ModulesConfigTool.Load();
            UpdateModuleConfigNames();
            setCurrentModule();
            PLC1 = new ModbusMaster_PLC(COM_PLC1, CurrentModuleCfg,4);
            PLC1.RefreshUI += RefreshUITestvalues;
            PLC1.ReadErrorEvent += PLC1_ReadErrorEvent;
            PLC2 = new ModbusMaster_PLC(COM_PLC2, CurrentModuleCfg,5) ;
            PLC2.RefreshUI += RefreshUITestvalues;
            PLC2.ReadErrorEvent += PLC1_ReadErrorEvent;
     //       PLC3 = new ModbusMaster_PLC(COM_PLC3, CurrentModuleCfg,3) ;
      //      PLC3.RefreshUI += RefreshUITestvalues;
     //       gasTester = new GasPressureTester(COM_KQ, CurrentModuleCfg);
            modbusPlcs.Add(PLC1);
            modbusPlcs.Add(PLC2);
    //        modbusPlcs.Add(PLC3);
            disPLC1 = new FrmDisplay() { MyProductName = CurrentModuleCfg.Name,_cfg=CurrentModuleCfg,PLCLocation=4 };
            disPLC2 = new FrmDisplay() { MyProductName = CurrentModuleCfg.Name,_cfg=CurrentModuleCfg,PLCLocation=5 };
   //         disPLC3 = new FrmDisplay() { MyProductName = CurrentModuleCfg.Name,_cfg=CurrentModuleCfg,PLCLocation=3 };
            displays.Add(disPLC1);
            displays.Add(disPLC2);
    //        displays.Add(disPLC3);
            InsertForm(disPLC1, pnl1);
            InsertForm(disPLC2, pnl2);
   //         InsertForm(disPLC3, pnl3);
 
               InsertForm(new frmQuery(),panel3);
                PLC1.ReadSettingValue();
                if (PLC1.PlcModbusStatus == false)
                {
                    MessageBox.Show(PLC1.ErrorMsg);
                    return;
                }
                PLC2.ReadSettingValue();
                if (PLC2.PlcModbusStatus == false)
                {
                    MessageBox.Show(PLC2.ErrorMsg);
                    return;
                }
            PLC1.Start();
            PLC2.Start();
   //         PLC3.Start();
        }

        void PLC1_ReadErrorEvent(string obj)
        {
            if (InvokeRequired)
            {
                MessageBox.Show(obj);
            }
        }

        void RefreshUITestvalues(int PlcLocation)
        {
            if (InvokeRequired)
            {
                Invoke(new Action<int>(RefreshUITestvalues),new object[]{PlcLocation});
                return;
            }
            RefreshTestValues(PlcLocation);
        }
        /// <summary>
        /// 设置当前的机种
        /// </summary>
        private void setCurrentModule()
        {
            if (moduleConfigs.Modules.Count > 0)
            {
          //      CurrentModuleCfg = moduleConfigs.Modules[0];
                CurrentModuleCfg = moduleConfigs.Find(_currentModule);
            }
        }
        /// <summary>
        /// 将机种设置里面的名称更新到Listbox1
        /// </summary>
        private void UpdateModuleConfigNames()
        {
            var s = from a in moduleConfigs.Modules select a.Name;
            listBox1.DataSource = s.ToList();
        }
        /// <summary>
        /// 更新串口设置里面Combobox里面的下拉值
        /// </summary>
        private void InitialControlValues()
        {
            SerialPortUtil.SetPortNameValues(cboComName1);
            SerialPortUtil.SetBauRateValues(cboBaud1);
            SerialPortUtil.SetStopBitValues(cboStopBits1);
            SerialPortUtil.SetDataBitsValues(cboDataBits1);
            SerialPortUtil.SetParityValues(cboParity1);
            SerialPortUtil.SetPortNameValues(cboComName2);
            SerialPortUtil.SetBauRateValues(cboBaud2);
            SerialPortUtil.SetStopBitValues(cboStopBits2);
            SerialPortUtil.SetDataBitsValues(cboDataBits2);
            SerialPortUtil.SetParityValues(cboParity2);
            SerialPortUtil.SetPortNameValues(cboComName3);
            SerialPortUtil.SetBauRateValues(cboBaud3);
            SerialPortUtil.SetStopBitValues(cboStopBits3);
            SerialPortUtil.SetDataBitsValues(cboDataBits3);
            SerialPortUtil.SetParityValues(cboParity3);

            SerialPortUtil.SetPortNameValues(cboComName4);
            SerialPortUtil.SetBauRateValues(cboBaud4);
            SerialPortUtil.SetStopBitValues(cboStopBits4);
            SerialPortUtil.SetDataBitsValues(cboDataBits4);
            SerialPortUtil.SetParityValues(cboParity4);
        }
        /// <summary>
        /// 将串口设置文件里面的值更新到界面中串口设置的当前值
        /// </summary>
        private void ConfigToUISetting()
        {
            cfg = ConfigTool.Load();

            COM_Configer cfgCom;
            cfgCom = cfg.Config_PLC1_COM;
            cboComName1.Text = cfgCom._Name;
            cboBaud1.Text = cfgCom._BuadRate;
            cboStopBits1.Text = cfgCom._StopBits;
            cboDataBits1.Text = cfgCom._DataBits;
            cboParity1.Text = cfgCom._Parity;

            cfgCom = cfg.Config_PLC2_COM;
            cboComName2.Text = cfgCom._Name;
            cboBaud2.Text = cfgCom._BuadRate;
            cboStopBits2.Text = cfgCom._StopBits;
            cboDataBits2.Text = cfgCom._DataBits;
            cboParity2.Text = cfgCom._Parity;

            cfgCom = cfg.Config_PLC3_COM;
            cboComName3.Text = cfgCom._Name;
            cboBaud3.Text = cfgCom._BuadRate;
            cboStopBits3.Text = cfgCom._StopBits;
            cboDataBits3.Text = cfgCom._DataBits;
            cboParity3.Text = cfgCom._Parity;

            cfgCom = cfg.Config_KQ_COM;
            cboComName4.Text = cfgCom._Name;
            cboBaud4.Text = cfgCom._BuadRate;
            cboStopBits4.Text = cfgCom._StopBits;
            cboDataBits4.Text = cfgCom._DataBits;
            cboParity4.Text = cfgCom._Parity;

        }
        /// <summary>
        /// 将界面中串口设置的当前值更新到设置文件
        /// </summary>
        private void UISettingToConfig()
        {
            cfg.Config_PLC1_COM._Name = cboComName1.Text;
            cfg.Config_PLC1_COM._BuadRate = cboBaud1.Text;
            cfg.Config_PLC1_COM._DataBits = cboDataBits1.Text;
            cfg.Config_PLC1_COM._StopBits = cboStopBits1.Text;
            cfg.Config_PLC1_COM._Parity = cboParity1.Text;

            cfg.Config_PLC2_COM._Name = cboComName2.Text;
            cfg.Config_PLC2_COM._BuadRate = cboBaud2.Text;
            cfg.Config_PLC2_COM._DataBits = cboDataBits2.Text;
            cfg.Config_PLC2_COM._StopBits = cboStopBits2.Text;
            cfg.Config_PLC2_COM._Parity = cboParity2.Text;

            cfg.Config_PLC3_COM._Name = cboComName3.Text;
            cfg.Config_PLC3_COM._BuadRate = cboBaud3.Text;
            cfg.Config_PLC3_COM._DataBits = cboDataBits3.Text;
            cfg.Config_PLC3_COM._StopBits = cboStopBits3.Text;
            cfg.Config_PLC3_COM._Parity = cboParity3.Text;

            cfg.Config_KQ_COM._Name = cboComName4.Text;
            cfg.Config_KQ_COM._BuadRate = cboBaud4.Text;
            cfg.Config_KQ_COM._DataBits = cboDataBits4.Text;
            cfg.Config_KQ_COM._StopBits = cboStopBits4.Text;
            cfg.Config_KQ_COM._Parity = cboParity4.Text;
            ConfigTool.Save(cfg);
        }
        /// <summary>
        /// 将设置更新到对应的串口控件
        /// </summary>
        /// <param name="COM"></param>
        /// <param name="cfg_Comport"></param>
        /// <returns></returns>
        private bool UpdateSettingToSerialport(SerialPort COM, COM_Configer cfg_Comport)
        {
            try
            {
                COM.Close();
                COM.PortName = cfg_Comport._Name;
                COM.BaudRate = int.Parse(cfg_Comport._BuadRate);
                COM.StopBits = SerialPortUtil.string_to_StopBits(cfg_Comport._StopBits);
                COM.Parity = SerialPortUtil.String_to_Parity(cfg_Comport._Parity);
                COM.DataBits = int.Parse(cfg_Comport._DataBits);
                COM.Open();
                return true;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return false;
            }
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            UISettingToConfig();
            UpdateSettingToSerialPortsAndUI();
        }
        /// <summary>
        /// 将设置更新到所有的串口，并显示连接状态
        /// </summary>
        private void UpdateSettingToSerialPortsAndUI()
        {
            if (UpdateSettingToSerialport(COM_PLC1, cfg.Config_PLC1_COM))
                led1.LEDSwitch=true;
            else
                led1.LEDSwitch=false;
            if (UpdateSettingToSerialport(COM_PLC2, cfg.Config_PLC2_COM))
                led2.LEDSwitch=true;
            else
                led2.LEDSwitch=false;
            led1.Invalidate();
            led2.Invalidate();

 //           if (UpdateSettingToSerialport(COM_PLC3, cfg.Config_PLC3_COM))
 //               led3.FillColor = Color.LimeGreen;
 //           else
 //               led3.FillColor = Color.Red;

 //           if (UpdateSettingToSerialport(COM_KQ , cfg.Config_KQ_COM))
  //              led4.FillColor = Color.LimeGreen;
 //           else
  //              led4.FillColor = Color.Red;
        }
        /// <summary>
        /// 将窗口添加到Panel中
        /// </summary>
        /// <param name="form"></param>
        /// <param name="pnl"></param>
        private void InsertForm(Form form, Panel pnl)
        {
            pnl.Controls.Clear();
            form.MdiParent = this;
            form.Parent = pnl;
            form.Dock = DockStyle.Fill;
            form.FormBorderStyle = FormBorderStyle.None;
            form.Show();
        }
        /// <summary>
        /// 添加机种设置被点击
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnAddModule_Click(object sender, EventArgs e)
        {
            ModuleConfig mcf = ModuleConfigTool.Load();
            moduleConfigs.Add(mcf);
            UpdateModuleConfigNames();
            FrmModuleConfig frm = new FrmModuleConfig(mcf, 1);
            frm.OnConfig += frm_OnConfig;
            listBox1.SelectedIndex = listBox1.Items.Count - 1;
            InsertForm(frm, panel1);
        }
        /// <summary>
        /// 设置回调
        /// </summary>
        /// <param name="obj">1表示取消，0表示保存设定</param>
        /// <param name="Name"></param>
        void frm_OnConfig(int obj, string Name)
        {
            if (obj == 0)//ok
            {
                moduleConfigs = ModulesConfigTool.Load();
            }
            else if (obj == 1)//cancel
            {
                ModulesConfigTool.Save(moduleConfigs);
            }
            UpdateModuleConfigNames();
        }
        /// <summary>
        /// 删除模块按钮被点击
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnDeleteModule_Click(object sender, EventArgs e)
        {
            if (listBox1.SelectedItems.Count == 0)
                return;
            moduleConfigs.Remove(listBox1.SelectedItems[0].ToString());
            UpdateModuleConfigNames();
        }
        /// <summary>
        /// 修改机种设定被点击
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnModifyModule_Click(object sender, EventArgs e)
        {
            if (listBox1.SelectedItems.Count == 0)
                return;
            ModuleConfig cfg = moduleConfigs.Find(listBox1.SelectedItems[0].ToString());
            FrmModuleConfig frm = new FrmModuleConfig(cfg, 2);
            frm.OnConfig += frm_OnConfig;
            InsertForm(frm, panel1);
        }
        /// <summary>
        /// 机种设定Listbox1内的选定项目变更
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            ModuleConfig cfg = moduleConfigs.Find(listBox1.SelectedItems[0].ToString());
            FrmModuleConfig frm = new FrmModuleConfig(cfg);
            frm.OnConfig += frm_OnConfig;
            InsertForm(frm, panel1);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            RefreshTestValues(1);
            RefreshTestValues(2);
            RefreshTestValues(3);
        }
        /// <summary>
        /// 刷新界面上的测试值
        /// </summary>
        private void RefreshTestValues(int PlcLocation)
        {
            UpdateTestValue2DataGridView(PlcLocation, dataGridView1);
            Update2DisplayView(PlcLocation);
        }

        /// <summary>
        /// 测试值更新到Datagridview
        /// </summary>
        /// <param name="PLCLocation"></param>
        /// <param name="dgv"></param>
        private void UpdateTestValue2DataGridView(int PLCLocation, DataGridView dgv)
        {
            List<DisplayItem> Items = new List<DisplayItem>();
            IEnumerable<SpecificationModel> s = from a in CurrentModuleCfg.Specifications where a.PLCLocation == PLCLocation select a;
            foreach (var b in s)
            {
                DisplayItem item1 = new DisplayItem()
                {
                    项目 = b.Description,
                    标准值 = b.StandardValue.ToString("f3"),
                    上限值 = b.UpperOffset.ToString("f3"),
                    下限值 = b.LowerOffset.ToString("f3"),
                    测试值 = b.TestValue.ToString("f3"),
                    测试结果 = b.TestResult ? "OK" : "NG"
                };
                Items.Add(item1);
            }
            dgv.DataSource = new BindingList<DisplayItem>(Items);
        }
        private void Update2DisplayView(int plcnum)
        {
            var s = from a in CurrentModuleCfg.Specifications where a.PLCLocation == plcnum select a;
            FrmDisplay dis = displays[plcnum - 4];
            ModbusMaster_PLC modPlc = modbusPlcs[plcnum - 4];
            dis.OKQty = modPlc._countManager.OKCount.ToString();
            dis.NGQty = modPlc._countManager.NGCount.ToString();
            dis.NGRate = modPlc._countManager.failRate;
            dis.OKRate = modPlc._countManager.passRate;
            dis.TotalQty = modPlc._countManager.totalCount.ToString();

            List<SubItemNGRate> SubItemsNgrates = new List<SubItemNGRate>();
            foreach (var b in s)
            {
                CountManager cm = modPlc.getSubCoubtManagerFromName(b.Description);
                SubItemNGRate sir = new SubItemNGRate();
                if (modPlc._countManager.totalCount > 0)
                {
                    sir.Name = b.Description;
                    sir.NgQty = cm.NGCount.ToString();
                    sir.NgRate =cm.failRate;
                }
                else
                {
                    sir.Name = b.Description;
                    sir.NgQty = cm.NGCount.ToString();
                    sir.NgRate = "0.00%";
                }
                SubItemsNgrates.Add(sir);
            }
            dis.UpadateSubItemNGRates(SubItemsNgrates);

            List<SaveItem> sis = new List<SaveItem>();
              var bs =s.ToList();
            if(bs.Count==3)
            {
                 SaveItem si = new SaveItem()
                {
                    检测时间 = DateTime.Now.ToString("HH:mm:ss"),
                    测试项目一 = bs[0].Description,
                    测试值一 = bs[0].TestValue.ToString("f3"),
                    测试结果一 = bs[0].TestResult ? "OK" : "NG",
                    测试项目二 = bs[1].Description,
                    测试值二 = bs[1].TestValue.ToString("f3"),
                    测试结果二 = bs[1].TestResult ? "OK" : "NG",
                    测试项目三 = bs[2].Description,
                    测试值三 = bs[2].TestValue.ToString("f3"),
                    测试结果三 = bs[2].TestResult ? "OK" : "NG"
                };
                 dis.Updatedgv(si);
            }
            if (bs.Count == 2)
            {
                SaveItem si = new SaveItem()
                {
                    检测时间 = DateTime.Now.ToString("HH:mm:ss"),
                    测试项目一 = bs[0].Description,
                    测试值一 = bs[0].TestValue.ToString("f3"),
                    测试结果一 = bs[0].TestResult ? "OK" : "NG",
                    测试项目二 = bs[1].Description,
                    测试值二 = bs[1].TestValue.ToString("f3"),
                    测试结果二 = bs[1].TestResult ? "OK" : "NG",
                    测试项目三 = "",
                    测试值三 = "",
                    测试结果三 = ""
                };
                dis.Updatedgv(si);
            }

            
            
        }


            
       
        private void button2_Click(object sender, EventArgs e)
        {
            PLC1.DoEvent();
            PLC2.DoEvent();
    //        PLC3.DoEvent();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            PLC1.ReadSettingValue();
            PLC2.ReadSettingValue();
    //        PLC3.ReadSettingValue();
        }

        private void button4_Click(object sender, EventArgs e)
        {
            PLC1.Start();
        }

        private void button5_Click(object sender, EventArgs e)
        {
            PLC2.Start();
        }

        private void button6_Click(object sender, EventArgs e)
        {
    //        PLC3.Start();
        }

        private void frmMain_FormClosed(object sender, FormClosedEventArgs e)
        {
            Application.Exit();
        }

        private void skinTabControl1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }



    }
    [Serializable]
    public class DisplayItem
    {
        public string 项目 { get; set; }
        public string 标准值 { get; set; }
        public string 上限值 { get; set; }
        public string 下限值 { get; set; }
        public string 测试值 { get; set; }
        public string 测试结果 { get; set; }
    }
    [Serializable]
    public class SaveItem
    {
        public string 检测时间 { get; set; }
        public string 测试项目一 { get; set; }
        public string 测试值一 { get; set; }
        public string 测试结果一 { get; set; }
        public string 测试项目二 { get; set; }
        public string 测试值二 { get; set; }
        public string 测试结果二 { get; set; }
        public string 测试项目三 { get; set; }
        public string 测试值三 { get; set; }
        public string 测试结果三 { get; set; }
    }
}
